import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:hixing_app/const/gaps.dart';
import 'package:hixing_app/extensions/iterable_ext.dart';
import 'package:hixing_app/utils/export_utils.dart';
import 'package:hixing_app/utils/permission.dart';
import 'package:hixing_app/views/test_view/ble_machine/BleDataUtils.dart';
import 'package:hixing_app/views/test_view/wifi_machine/wifi_index.dart';
import 'package:hixing_app/widgets/toast/toast.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image/image.dart' as imgUtils;

class CurrentConnectDevice extends StatefulWidget {
  const CurrentConnectDevice({super.key, required this.detailData});

  final ScanResult detailData;

  @override
  _CurrentConnectDeviceState createState() => _CurrentConnectDeviceState();
}

class _CurrentConnectDeviceState extends State<CurrentConnectDevice> {
  // String serviceId = '49535343-FE7D-4AE5-8FA9-9FAFD205E455';
  // String writId = '49535343-8841-43F4-A8D4-ECBE34729BB3';
  // String notifyId = '49535343-1E4D-4BD9-BA61-23C647249616';
  String serviceId = '0000FFF0-0000-1000-8000-00805F9B34FB';
  String writId = '0000FFF2-0000-1000-8000-00805F9B34FB';
  String notifyId = '0000FFF1-0000-1000-8000-00805F9B34FB';

  Map<int, dynamic> deviceService = {
    // lp3 lp4
    0: {
      "serviceId": '0000FFF0-0000-1000-8000-00805F9B34FB',
      "writId": "0000FFF2-0000-1000-8000-00805F9B34FB",
      "notifyId": "0000FFF1-0000-1000-8000-00805F9B34FB"
    },
    // lp2
    // 1: {
    //   "serviceId": '49535343-FE7D-4AE5-8FA9-9FAFD205E455',
    //   "writId": "49535343-8841-43F4-A8D4-ECBE34729BB3",
    //   "notifyId": "49535343-1E4D-4BD9-BA61-23C647249616"
    // }
    // lp5的id
    1: {
      "serviceId": '0000ABF0-0000-1000-8000-00805F9B34FB',
      "writId": "0000abf3-0000-1000-8000-00805f9b34fb", // 1 蓝牙指令  3 at模式通信
      "notifyId": "0000abf4-0000-1000-8000-00805f9b34fb" //2 蓝牙指令  4 at模式通信
    }
  };

  StreamSubscription<List<int>>? _lastValueSubscription;

  // 当前服务
  BluetoothService? currentService;

  // 写入特征
  BluetoothCharacteristic? writeCh;

  // 读取特征
  BluetoothCharacteristic? notifyCh;

  int startTime = 0;

  int mtuOption = 8;

  //speed
  String speed = "";

  // at指令，蓝牙配网的时候用
  bool isAt = false;

  // 读取的最新的值
  List<int> _value = [];
  List<int> _sendVal = [];
  List<Uint8List> splitImgList = [];

  // 文件大小
  late int fileSize = 0;

  int imgSplitIndex = 0;

  // 是否传输完成
  bool isFinish = false;

  // 传输时间
  late int completeTime = 0;

  // int mtu = 0;

  // 传输的文件内容
  File? file;
  late Uint8List imageBytes;

  // 使用ImagePicker前必须先实例化
  final ImagePicker picker = ImagePicker();

  @override
  void dispose() {
    // TODO: implement dispose
    _lastValueSubscription?.cancel();
    super.dispose();
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    serviceId = deviceService[1]["serviceId"];
    writId = deviceService[1]["writId"];
    notifyId = deviceService[1]["notifyId"];
    getService();
    // getMtu();
  }

  Future<void> openGallery() async {
    bool isImg = await PermissionUtils.requestPhotosStorage();

    final XFile? image = await picker.pickImage(source: ImageSource.gallery);
    print("选择的图片${image!.name}");
    File imageFile = File(image.path);
    ByteData _data = imageFile.readAsBytesSync().buffer.asByteData();

    setState(() {
      file = File(image.path);

      // pxImg = imgData1;
    });
  }

  Future<void> getService() async {
    List<BluetoothService> _list =
        await widget.detailData.device.discoverServices();
    for (var service in _list) {
      print("serviceId:${service.serviceUuid.str128}");
      if (service.serviceUuid.str128.toUpperCase() == serviceId.toUpperCase()) {
        currentService = service;
        for (var ch in currentService!.characteristics) {
          print("特征ID:${ch.uuid.str128}");
          if (ch.uuid.str128.toUpperCase() == writId.toUpperCase()) {
            writeCh = ch;
          } else if (ch.uuid.str128.toUpperCase() == notifyId.toUpperCase()) {
            notifyCh = ch;
          }
        }
      }
    }
    await notifyCh?.setNotifyValue(true);
    // 订阅通知
    _lastValueSubscription = notifyCh!.lastValueStream.listen((value) {
      _value = value;
      print("接受到下行设备返回的响应：${value}");
      // 设备收到传输文件指令，进入大数据传输模式，可以传输文件了
      if (mounted) {
        if (isAt) {
          String atStr = utf8.decode(value);
          print("wifi配网指令响应：$atStr");
          if (atStr.startsWith("B1.0=")) {
            // 配网成功
            Get.to(() => WifiIndex(address: atStr.split("=")[1]));
          } else {
            print("配网失败");
          }
        }
        if (value.isNotEmpty && value.length > 6) {
          if (value[3] == 5 && value[4] == 1 && value[5] == 1) {
            // 启动大数据发送模式======
            // start send file
            sendFile();
          } else if (value[3] == 5 && value[4] == 2) {
            // 传输结束
            print("传输结束：${value[5] == 1 ? "接收成功" : "接受失败"}");
            // 传输结束也调用一下，如果有分包操作，分包传送
            // reSendFile();
            if (mounted) {
              if (value[5] == 1) {
                finishSend();
              }
            }
          }
        }
      }
      if (mounted) {
        setState(() {});
      }
    });
  }

  void finishSend() {
    isFinish = true;
    completeTime = DateTime.now().millisecondsSinceEpoch - startTime;
    file = null;
    speed = "${(fileSize / (completeTime * 0.001)).toStringAsFixed(2)}k/S";
    splitImgList.clear();
  }

  Future<Uint8List> compressImage(Uint8List imageData) async {
    // 使用image库压缩图片
    imgUtils.Image? image = imgUtils.decodeImage(imageData);
    imgUtils.Image resized = imgUtils.copyResize(image!, width: 200);
    return Uint8List.fromList(imgUtils.encodeJpg(resized, quality: 85));
  }

  List<int> getImgHeader() {
    int widthHigh = (200 >> 8) & 0xFF;
    int widthLow = 200 & 0xFF;
    int heightHigh = (200 >> 8) & 0xFF;
    int heightLow = 200 & 0xFF;

    List<int> imgBytesLength = getImgBytesLength();
    // 处理分包列表，发送一次，就把分包列表的第0个删除
    List<int> imgList = [
      0x10, //图片数据  1bytes
      widthHigh, // 宽高八位 1bytes
      widthLow, //宽低八位 1bytes
      heightHigh, // 高高八位 1bytes
      heightLow, // 高低八位 1bytes
      0x00, // 图片name 4bytes
      0x00, // 图片name 4bytes
      0x00, // 图片name 4bytes
      0x00, // 图片name 4bytes
      0x00, // PX分辨率 1bytes
      0x00, // D3 2 bytes
      0x00, // D3 2 bytes
      0x00, // D4 2 bytes
      0x00, // D4 2 bytes
      0x00, // D5 2 bytes
      0x00, // D5 2 bytes
      0x00, //Dir
      0x00,
      0x00,
      0x00,
      0x00,
      // ...imgBytesLength
      // ..._fileLength, // 图片长度length 4 bytes
    ];
    // int recoupNum = 64 - imgList.length;
    int recoupNum = 64 - imgList.length;
    // // 补齐64个字节
    for (int i = 0; i < recoupNum; i++) {
      imgList.add(0x00);
    }
    print("返回的请求头长度：${imgList.length}");
    return imgList;
  }

  List<int> getImgBytesLength() {
    // 所有包的请求头长度都要算回去
    int _listLength = imageBytes.length + 64;
    // 把文件长度转成4个bytes
    List<int> _imgBytesLength = BleDataUtils.intToNBytesHex(_listLength, 4);
    print("返回的字节数组长度值：${_listLength}");
    return _imgBytesLength;
  }

  // 发送文件
  Future<void> sendFile() async {
    isFinish = false;
    startTime = DateTime.now().millisecondsSinceEpoch;
    toWriteImg();
  }

  Future<void> toWriteImg() async {
    // 把所有数据一次性发过去
    List<int> _imgHeader = getImgHeader();
    for (int index = 0; index < splitImgList.length; index++) {
      List<int> _arr;
      // 第一次发包的时候带上头
      if (index == 0) {
        _arr = [..._imgHeader, ...splitImgList[index]];
      } else {
        _arr = splitImgList[index];
      }
      await Future.delayed(const Duration(milliseconds: 20));
      writToCh(_arr);
    }
  }

  Future onWritePressed() async {
    // 退出
    List<int> exitStrList = [0xFF, 0x00, 0x00, 0x00, 0x00, 0x00];
    // 查询
    List<int> chekStrList = [0x00, 0x04, 0x00, 0x00, 0x00, 0x00];
    // 查询设置
    List<int> chekSettingStrList = [0x00, 0x02, 0x00, 0x00, 0x00, 0x00];
    List<int> exitList = BleDataUtils.transData(exitStrList);
    List<int> checkList = BleDataUtils.transData(chekStrList);
    List<int> checkSettingList = BleDataUtils.transData(chekSettingStrList);

    // 发送数据给雕刻机
    await writToCh(checkSettingList);
  }

  // 发送数据到写入特征
  Future<void> writToCh(List<int> data) async {
    // print("当前的发送到设备的信息${data}");
    _sendVal = data;
    try {
      await writeCh!.write(data,
          withoutResponse: writeCh!.properties.writeWithoutResponse);
      // Snackbar.show(ABC.c, "Write: Success", success: true);
      if (writeCh!.properties.read) {
        //接受雕刻机返回信息
        await writeCh!.read();
      }
    } catch (e) {
      // Snackbar.show(ABC.c, prettyException("Write Error:", e), success: false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('当前连接设备'),
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text("服务ID：${serviceId}"),
            Text("特征读取ID：${notifyId}"),
            Text("特征写入ID：${writId}"),
            ElevatedButton(
              onPressed: () {
                if (serviceId == deviceService[0]["serviceId"]) {
                  serviceId = deviceService[1]["serviceId"];
                  writId = deviceService[1]["writId"];
                  notifyId = deviceService[1]["notifyId"];
                } else {
                  serviceId = deviceService[0]["serviceId"];
                  writId = deviceService[0]["writId"];
                  notifyId = deviceService[0]["notifyId"];
                }
                setState(() {});
              },
              child: Text("切换服务以及特征ID"),
            ),
            Text("name：${widget.detailData.device.advName}"),
            Text("remoteId：${widget.detailData.device.remoteId}"),
            ElevatedButton(
              onPressed: () async {},
              child: Text("雕刻机通讯"),
            ),
            Text("APP设备发送的值：${_sendVal.listIntToHex}"),
            ElevatedButton(
              onPressed: () async {
                onWritePressed();
              },
              child: Text("发送数据"),
            ),
            Text("读取下行设备回复的值：${_value.listIntToHex}"),
            ElevatedButton(
              onPressed: () async {},
              child: Text("当前通知订阅状态:${notifyCh?.isNotifying}"),
            ),
            Gaps.vGap20,
            Row(
              children: [
                ElevatedButton(
                    onPressed: () {
                      openGallery();
                    },
                    child: Text("选择文件")),
                Gaps.hGap10,
                ElevatedButton(
                    onPressed: () {
                      if (file == null) {
                        AppToast.showText("请选择文件后重试");
                        return;
                      }
                      // imageBytes = file!.readAsBytesSync();
                      int sizeInKb = 100; // 大小为1000KB
                      int sizeInBytes = sizeInKb * 1024; // 转换为字节
                      imageBytes = Uint8List(sizeInBytes * 1); // 创建Uint8List
                      fileSize = imageBytes.length ~/ 1024;
                      splitImgList.clear();

                      // 图片分包后的列表
                      splitImgList = BleDataUtils.splitImageData(imageBytes,
                          widget.detailData.device.mtuNow - mtuOption);
                      print("当前发送的数组：${splitImgList.length}");
                      List<int> imgBytesLength = getImgBytesLength();
                      print(
                          "开启大数据指令前的 length数据：${imgBytesLength.listIntToHex}");
                      List<int> sendList = BleDataUtils.transData([
                        0x05, // 功能  bytes 1
                        0x01, // state  bytes 1
                        ...imgBytesLength, // img length data  bytes 4
                        // "${file!.lengthSync()}", //img
                        0x00, // Data5
                        0x01, // mount
                        0x00 // name
                      ]);

                      // print("发送图片的指令：${sendList}");
                      writToCh(sendList);
                      //调焦指令
                      // List<int> focusList = BleDataUtils.transData([
                      //   "04", // 功能
                      //   "02", // state
                      //   "01", // dir
                      //   "01", // step
                      //   "00", // data3
                      //   "00", // data 4
                      // ]);
                      // writToCh(focusList);
                    },
                    child: Text("发送文件")),
                Gaps.hGap10,
                ElevatedButton(
                    onPressed: () {
                      isAt = true;
                      String networkInfo = 'A1="Xiaomi_E511","Hi@Yanfa123"';
                      List<int> networkInfoBytes = []; // 编码
                      networkInfoBytes
                          .addAll(utf8.encode(networkInfo)); // 为UTF-8
                      // networkInfoBytes.add(0x00); // 添加结束符
                      // print("WiFi配网指令：${networkInfoBytes}");
                      // List<int> wifiCommand = [
                      //   0x08, // 功能
                      //   0x01, // data0
                      //   0x00, // data1
                      //   ...networkInfoBytes,
                      //   0x00,
                      //   0x00,
                      // ];
                      print(networkInfoBytes);
                      writToCh(networkInfoBytes);
                    },
                    child: Text("WiFi配网")),
              ],
            ),
            Text("文件大小：${fileSize}K"),
            Text("传输时间：${completeTime} ms"),
            Text("分包大小：${widget.detailData.device.mtuNow - mtuOption}"),
            Text("传输速度：${speed}"),
            Text("发送文件：${file?.path}"),
            Text("是否传输完成：${isFinish}"),
            Gaps.getVGap(ScreenUI.bottomSafeHeight + 20),
          ],
        ),
      ),
    );
  }
}
